package com.party.core.service.activity.impl;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.party.common.constant.Constant;
import com.party.common.paging.Page;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.PartyCode;
import com.party.common.utils.StringUtils;
import com.party.core.dao.read.activity.ActivityReadDao;
import com.party.core.dao.read.counterfoil.CounterfoilReadDao;
import com.party.core.dao.read.crowdfund.ProjectReadDao;
import com.party.core.dao.write.activity.ActivityWriteDao;
import com.party.core.exception.BusinessException;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.activity.*;
import com.party.core.model.city.Area;
import com.party.core.model.city.City;
import com.party.core.model.counterfoil.Counterfoil;
import com.party.core.model.crowdfund.Project;
import com.party.core.model.order.OrderForm;
import com.party.core.model.order.PaymentState;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.city.IAreaService;
import com.party.core.service.city.ICityService;
import com.party.core.service.order.IOrderFormService;
import com.sun.istack.NotNull;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * ActivityService活动服务实现
 *
 * @author Wesley
 * @data 16/9/5 17:28 .
 */

@Service
public class ActivityService implements IActivityService{

    @Autowired
    private ActivityReadDao activityReadDao;

    @Autowired
    private ActivityWriteDao activityWriteDao;
    @Autowired
    private IAreaService areaService;
    @Autowired
    private ICityService cityService;
    @Autowired
    private CounterfoilReadDao counterfoilReadDao;
    @Autowired
    private ProjectReadDao projectReadDao;

    @Autowired
    private IOrderFormService orderFormService;

    /**
     * 插入活动数据
     * @param activity 活动实体
     * @return 插入结果（true/false）
     */
    public String insert(Activity activity) {
        BaseModel.preInsert(activity);
        boolean result = activityWriteDao.insert(activity);
        if (result){
            return activity.getId();
        }
        return null;
    }

    /**
     * 更新活动信息
     * @param activity 活动实体
     * @return 更新结果（true/false）
     */
    public boolean update(Activity activity) {
        if (null == activity)
            return false;
        if (null != activity.getUpdateDate()) {
            activity.setUpdateDate(new Date());
        }
        return activityWriteDao.update(activity);
    }

    /**
     * 逻辑删除活动数据
     * @param id 活动实体主键
     * @return 删除结果（true/false）
     */
    public boolean deleteLogic(@NotNull String id) {
        if (StringUtils.isBlank(id))
            return false;

        return activityWriteDao.deleteLogic(id);
    }

    /**
     * 物理删除活动数据
     * @param id 活动实体主键
     * @return 删除结果（true/false）
     */
    public boolean delete(@NotNull String id) {
        if (StringUtils.isBlank(id))
            return false;

        return activityWriteDao.delete(id);
    }

    /**
     * 批量逻辑删除活动数据
     * @param ids 主键集合
     * @return 删除结果（true/false）
     */
    public boolean batchDeleteLogic(@NotNull Set<String> ids) {
        if (CollectionUtils.isEmpty(ids))
            return false;

        return activityWriteDao.batchDeleteLogic(ids);
    }

    /**
     * 批量物理删除活动数据
     * @param ids 主键集合
     * @return 删除结果（true/false）
     */
    public boolean batchDelete(@NotNull Set<String> ids) {
        if (CollectionUtils.isEmpty(ids))
            return false;

        return activityWriteDao.batchDelete(ids);
    }

    /**
     * 根据主键获取活动实体数据
     * @param id 主键
     * @return 活动实体
     */
    public Activity get(String id) {
        if (StringUtils.isBlank(id))
            return null;

        return activityReadDao.get(id);
    }

    /**
     * 分页查询活动列表
     * @param activity 活动实体
     * @param page 分页信息
     * @return 活动列表
     */
    public List<Activity> listPage(Activity activity, Page page) {
        return activityReadDao.listPage(activity, page);
    }

    /**
     * 查询所有活动数据
     * @param activity 活动实体
     * @return 活动列表
     */
    public List<Activity> list(Activity activity) {
        return activityReadDao.listPage(activity, null);
    }

    /**
     * 查询所有活动
     * @return 活动列表
     */
    @Override
    public List<Activity> listAll() {
        return activityReadDao.listPage(null, null);
    }

    /**
     * 根据活动主键集合查询活动数据
     * @param ids 主键集合
     * @param activity 活动实体
     * @param page 分页信息
     * @return 活动列表
     */
    public List<Activity> batchList(@NotNull Set<String> ids, Activity activity, Page page) {
        if (CollectionUtils.isEmpty(ids))
            return Collections.EMPTY_LIST;

        return activityReadDao.batchList(ids, new HashedMap(), page);
    }

	public List<Activity> joinedList(Activity activity) {
		return activityReadDao.joinedList(activity);
	}

	@Override
	public List<ActivityWithMemberPartner> webListPage(ActivityWithMemberPartner activity, Map<String, Object> params, Page page) {
		return activityReadDao.webListPage(activity, params, page);
	}

    /**
     * 根据事件编号统计
     * @param eventId 事件编号
     * @return 统计结果
     */
    @Override
    public Activity countForEventId(String eventId) {
        return activityReadDao.countForEventId(eventId);
    }

    @Override
    public Integer getCount(Activity activity) {
        return activityReadDao.getCount(activity);
    }

    @Override
    public List<Map<String, Object>> copartnerListPage(Map<String, Object> params, Page page) {
        return activityReadDao.copartnerListPage(params, page);
    }

    @Override
    public Integer getCountByEventId(String eventId) {
        return activityReadDao.getCountByEventId(eventId);
    }

    @Override
    public List<String> getOrgNotEventId() {
        return activityReadDao.getOrgNotEventId();
    }

    @Override
    public String getShowAddress(Activity activity) {
        City c = cityService.get(activity.getCityId());
        String address = c != null ? c.getName() : "";
        Area area = areaService.get(activity.getArea());
        if (area != null) {
            address += area.getName();
        } else {
            address += activity.getArea() != null ? activity.getArea() : "";
        }
        address += activity.getPlace() != null ? activity.getPlace() : "";
        return address;
    }

    @Override
    public List<Map<String, Object>> getActivityCopartner(String eventId) {
        return activityReadDao.getActivityCopartner(eventId);
    }

    /**
     * 统计销售量
     * @param id 编号
     * @param payment 金额
     */
    @Override
    public void countSales(String id, Float payment) {
        Activity activity = this.get(id);
        activity.setSalesNum(activity.getSalesNum() + 1);

        Float amount =  BigDecimalUtils.add(activity.getSalesAmount(), payment);
        amount = BigDecimalUtils.round(amount, 2);
        activity.setSalesAmount(amount);
        this.update(activity);
    }

    /**
     * 统计众筹项目浏览量
     * @param id 众筹编号
     * @return 浏览量
     */
    @Override
    public Integer crowdfundView(String id) {
        Activity activity = this.get(id);
        Integer projectViewNum = projectReadDao.viewNumForTargetId(id);
        projectViewNum = null == projectViewNum ? 0 : projectViewNum;
        if (null != activity){
            return activity.getReadNum() + projectViewNum;
        }
        return projectViewNum;
    }

    /**
     * 发布者的其他项目
     * @param memberId 会员编号
     * @param id 项目编号
     * @return 项目列表
     */
    @Override
    public List<Activity> otherActivity(String memberId, String id, String authorId) {
        Activity activity = new Activity();
        activity.setMember(memberId);
        activity.setStatus(0);
        activity.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        activity.setIsCrowdfunded(Constant.IS_CROWDFUNDED);
        List<Activity> list = this.list(activity);
        List<Activity> newList = Lists.newArrayList();

        for (Activity a : list) {
            if (StringUtils.isNotEmpty(authorId)) {
                Project myProject = projectReadDao.getMyProject(a.getId(), authorId);
                if (null != myProject && Constant.IS_SUCCESS.equals(myProject.getIsSuccess())) {
                    continue;
                }
            }
            if (a.getId().equals(id)) {
                continue;
            }
            if(a.getIsMultiple() == YesNoStatus.YES.getCode()){
                continue;
            }
            List<Counterfoil> counterfoils = counterfoilReadDao.listPage(new Counterfoil(a.getEventId(),
                    Constant.BUSINESS_TYPE_CROWDFUND), null);
            if (counterfoils.size() > 1) {
                Project myProject = projectReadDao.getMyProject(a.getId(), authorId);
                if (null == myProject) {
                    continue;
                }
            }
            newList.add(a);
        }
        return newList;
    }


    /**
     * 订单下单
     *
     * @param parameter 请求参数
     */
    @Override
    public String bookOrder(BookOrderParameter parameter)throws BusinessException {
        OrderForm orderForm = new OrderForm();
        orderForm.setMemberId(parameter.getMemberId());
        if (null == parameter.getPayment()){
            throw new BusinessException(PartyCode.PARAMETER_ILLEGAL, "下单失败,金额为空");
        }

        orderForm.setMerchantId(parameter.getMerchantId());
        orderForm.setGoodsId(parameter.getActivityId());
        orderForm.setUnit(parameter.getUnit());
        orderForm.setLinkman(parameter.getLinkman());
        orderForm.setPhone(parameter.getPhone());
        orderForm.setType(parameter.getType());
        orderForm.setStatus(parameter.getStatus());
        orderForm.setIsPay(PaymentState.NO_PAY.getCode());

        if (!Strings.isNullOrEmpty(parameter.getStoreGoodsId())){
            orderForm.setStoreGoodsId(parameter.getStoreGoodsId());
        }

        double payment =  BigDecimalUtils.mul(parameter.getPayment(), parameter.getUnit());
        double payment2 = BigDecimalUtils.round(payment, 2);
        orderForm.setPayment((float) payment2);
        orderForm.setTitle(parameter.getTitle());
        orderForm.setInitiatorId(parameter.getInitiatorId());
        orderFormService.insert(orderForm);
        return orderForm.getId();
    }

    @Override
    public List<Map<String, Object>> cosponsorList(Map<String, Object> params, Page page) {
        return activityReadDao.cosponsorList(params, page);
    }
    /**
     * 通过发布者id获取项目（在当前项目的参与者有支持者的情况下）
     *
     * @param activityId  项目id
     * @return
     */
    @Override
    public List<Activity> findByIdActivitys(String activityId) {
        return activityReadDao.findByIdActivitys(activityId);
    }

    @Override
    public String getShowAddressMap(Activity activity, Map<String, String> mmp) {
        City c = cityService.get(activity.getCityId());
        String address = c != null ? c.getName() : "";
        mmp.put("city", c != null ? c.getName() : "");
        Area area = areaService.get(activity.getArea());
        if (area != null) {
            mmp.put("area", area.getName());
            address += area.getName();
        } else {
            mmp.put("area", activity.getArea() != null ? activity.getArea() : "");
            address += activity.getArea() != null ? activity.getArea() : "";
        }
        mmp.put("place", activity.getPlace() != null ? activity.getPlace() : "");
        address += activity.getPlace() != null ? activity.getPlace() : "";
        return address;
    }

    @Override
    public List<Map<String, Object>> copartnerListPage2(Map<String, Object> params, Page page) {
        return activityReadDao.copartnerListPage2(params, page);
    }

    @Override
    public List<DistributionActivity> listForDistribution(Activity activity, Map<String, Object> params, Page page) {
        return activityReadDao.listForDistribution(activity, params, page);
    }
    /**
     * 锁行查询活动实体
     *
     * @param id
     * @return 活动实体
     */
    @Override
    public Activity rowLockQueryActivity(String id){
        return activityReadDao.rowLockQueryActivity(id);
    }

    /**
    * @Author hzq
    * @Description //根据众筹id找项目
    * @Date 18:13 2019/4/10
    * @param projectId
    * @return
    **/
    @Override
    public Activity findByProjectId(String projectId) {
        return activityReadDao.findByProjectId(projectId);
    }

    @Override
    public List<ActivityWithMemberPartner> courseWebListPage(ActivityWithMemberPartner activity, Map<String, Object> params, Page page) {
        return activityReadDao.courseWebListPage(activity, params, page);
    }

    @Override
    public Integer getActivityType(Activity activity) {
        if (null != activity.getIsCrowdfunded() && new Integer(1).equals(activity.getIsCrowdfunded())) {
            return ActivityType.CROWDFUND.getCode();
        } else if (null != activity.getActivityType() && new Integer(-1).equals(activity.getIsCrowdfunded())
                && ActivityType.COURSE.getCode().equals(activity.getActivityType())) {
            return ActivityType.COURSE.getCode();
        } else if (null != activity.getIsCrowdfunded() && new Integer(0).equals(activity.getIsCrowdfunded())) {
            return ActivityType.ACTIVITY.getCode();
        }
        return null;
    }

    @Override
    public Activity getZcNumByTargetId(String targetId, boolean queryZcNum) {
        return activityReadDao.getZcNumByTargetId(targetId, queryZcNum);
    }

    @Override
    public Integer findByCosponsorId(String cosponsorId) {
        return activityReadDao.findByCosponsorId(cosponsorId);
    }

    @Override
    public List<String> getXzgsActivityList(String title, String xzgsMemberId) {
        return activityReadDao.getXzgsActivityList(title, xzgsMemberId);
    }

    @Override
    public void updateMember(String activityId, String memberId) {
        activityWriteDao.updateMember(activityId, memberId);
    }

    @Override
    public Integer getActNumByMemberGroupId(List<String> memberGroupIds ,Map<String, Object> params) {
        return activityReadDao.getActNumByMemberGroupId(memberGroupIds,params);
    }

    @Override
    public List<Activity> getActivitysByEventId(String eventId) {
        return activityReadDao.getActivitysByEventId(eventId);
    }
}
